/**
 * @class 引力透镜组件
 * @author DuskyHuang 圣子
 * @description 引力透镜是因为黑洞强大的引力造成周边光线弯曲的现象。
 * @description 我们使用shader和渲染纹理来近似模拟这个现象。
*/

import { _decorator, Material, renderer, Color, Vec4, Node, Component, Sprite } from 'cc';
import { utils } from 'cfw';
import { RelativeCamera } from './relative-camera';
import { SceneGraph } from 'const';
const { ccclass, property } = _decorator;
const { findCamera, findComp } = utils;

@ccclass('cocosmos.gravitational-lens')
export class GravitationalLens extends Component {

    @property
    public scaleFactor: number = 10.0;

    @property(Node)
    public hole: Node = null;

    @property(Color)
    public get holeColor(): Color { return this._holeColor; }
    public set holeColor(arg: Color) { this._holeColor = arg; }
    
    @property(Color)
    public get photonColor(): Color { return this._photonColor; }
    public set photonColor(arg: Color) { this._photonColor = arg; }

    @property(Color)
    private _holeColor: Color = Color.WHITE.clone();
    @property(Color)
    private _photonColor: Color = Color.WHITE.clone();
    @property
    private _holes: Vec4 = new Vec4(0, 0, 0, 1);
    @property
    private _args: Vec4 = new Vec4(0, 0, 0, 0);

    protected lateUpdate(): void {
        if (this._material && this._pass0 && this.hole?.active) {
            const { x, y, z } = this.hole.worldPosition;
            this._holes.set(x, y, z, this.hole.worldScale.x * this.scaleFactor);
            this._pass0.setUniform(this._handleHColor, this._holeColor);
            this._pass0.setUniform(this._handlePColor, this._photonColor);
            this._pass0.setUniform(this._handleHoles, this._holes);
            this._args.x = 0.0075;
            this._args.y = Math.cos(Math.parseRadian(this._relCam.heightAngle));
            this._pass0.setUniform(this._handleArgs, this._args);
        }
    }

    private _pass0: renderer.Pass = null;
    private _handleHColor: handle = 0;
    private _handlePColor: handle = 0;
    private _handleHoles: handle = 0;
    private _handleArgs: handle = 0;
    private _material: Material;
    private _relCam: RelativeCamera;
    protected onLoad(): void {
        this._relCam = findComp(RelativeCamera, COSMOS, MAIN);
        this._material = this.getComponent(Sprite).customMaterial;
        if (this._material) {
            this._pass0 = this._material.passes[0];
            this._handleHColor = this._pass0.getHandle('holeColor');
            this._handlePColor = this._pass0.getHandle('photonColor');
            this._handleHoles = this._pass0.getHandle('holes');
            this._handleArgs = this._pass0.getHandle('args');
        }
    }

    protected start(): void {
    }
}

const { COSMOS, Cameras: { MAIN } } = SceneGraph;